﻿namespace Yaaf.WP7.NativeAccess.Registry.Internals.HTC
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using Yaaf.WP7.NativeAccess.ComWrapper.HTC.COM_RegRw;
    using Yaaf.WP7.NativeAccess.Helper;
    using Yaaf.WP7.NativeAccess.Provision;
    using Yaaf.WP7.NativeAccess.Registry;
    using Yaaf.WP7.NativeAccess.Registry.Internals.AllDevices;
    using Yaaf.WP7.NativeAccess.Registry.Internals.HTC.COM_NativeAccess;

    using Registry = Yaaf.WP7.NativeAccess.Registry.Internals.HTC.COM_NativeAccess.Registry;
    using RegistryKey = Yaaf.WP7.NativeAccess.Registry.Internals.HTC.COM_NativeAccess.RegistryKey;

    internal class HtcRegistryAccess : ProvisionRegistryBase
    {
        public override RegistryValueKind GetValueType(RootKey root, string subkey, string valueName)
        {
            using (var htc = new HTCRegistry())
            {
                uint num;
                if (htc.RegistryGetDWORD(root, subkey, valueName, out num))
                {
                    return RegistryValueKind.DWord;
                }

                StringBuilder str;
                if (htc.RegistryGetString(root, subkey, valueName, out str))
                {
                    return RegistryValueKind.String;
                }
            }

            RegistryKey rootKey = GetRootKey(root);
            var subKey = rootKey.OpenSubKey(subkey);
            if (subKey != null)
            {
                var strValue = subKey.GetStringValue(valueName);
                if (strValue != null)
                {
                    return RegistryValueKind.String;
                }

                var value = subKey.GetIntegerValue(valueName, -1);
                if (value != -1)
                {
                    return RegistryValueKind.DWord;
                }
            }

            throw new UnauthorizedAccessException("this key does not exist or the value is not supported");
        }

        public override object GetValue(RootKey root, string subkey, string valueName)
        {
            using (var htc = new HTCRegistry())
            {
                uint num;
                if (htc.RegistryGetDWORD(root, subkey, valueName, out num))
                {
                    return num;
                }

                StringBuilder str;
                if (htc.RegistryGetString(root, subkey, valueName, out str))
                {
                    return str.ToString();
                }
            }

            RegistryKey rootKey = GetRootKey(root);
            var subKey = rootKey.OpenSubKey(subkey);
            if (subKey != null)
            {
                var strValue = subKey.GetStringValue(valueName);
                if (strValue != null)
                {
                    return strValue;
                }

                var value = subKey.GetIntegerValue(valueName, -1);
                if (value != -1)
                {
                    return value;
                }
            }
            throw new UnauthorizedAccessException("this key does not exist or the value is not supported");
        }


        private static RegistryKey GetRootKey(RootKey root)
        {
            RegistryKey rootKey;
            switch (root)
            {
                case RootKey.E_HKEY_CLASSES_ROOT:
                    rootKey = Registry.ClassesRoot;
                    break;
                case RootKey.E_HKEY_CURRENT_USER:
                    rootKey = Registry.CurrentUser;
                    break;
                case RootKey.E_HKEY_LOCAL_MACHINE:
                    rootKey = Registry.LocalMachine;
                    break;
                case RootKey.E_HKEY_USERS:
                    rootKey = Registry.CurrentUser;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            return rootKey;
        }
    }
}